﻿// <copyright file="KingExtension.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains the class KingExtension</summary>

namespace Sqwarea.GameLogic.Extensions
{
    using System;
    using Sqwarea.Persistence;

    /// <summary>
    /// Provide extensions of king for GameLogic
    /// </summary>
    public static class KingExtension
    {
        /// <summary>
        /// Return true if the king is neutral and update the King Id to neutral if it is the case.
        /// Notice that some Kings can have a id != NeutralKingId because of dead king.
        /// Always use this function if you want to know if a king is neutral or not.
        /// </summary>
        /// <param name="king">The considered king</param>
        /// <returns>See summary</returns>
        public static bool IsNeutral(this King king)
        {
            if (king.Id == King.NeutralKingId)
            {
                return true;
            }

            if (king.OpenId == null)
            {
                king.Id = King.NeutralKingId;
                return true;
            }

            return false;
        }

        /// <summary>
        /// This function has the same behaviour as <see cref="IsNeutral"/> but do not return if king is neutral or not.
        /// </summary>
        /// <param name="king">The considered king</param>
        public static void UpdateNeutralId(this King king)
        {
            if (king.OpenId == null)
            {
                king.Id = King.NeutralKingId;
            }
        }

        /// <summary>
        /// Updates the number of troops in the Royal Academy.
        /// </summary>
        /// <param name="king">The considered king</param>
        public static void UpdateAcademyTroops(this King king)
        {
            DateTimeOffset dto = DateTimeOffset.Now;
            TimeSpan ts = dto.Subtract(king.LastAcademyTroopsUpdate);
            double hourlygen;

            if (king.SquaresNumber <= GlobalParameters.TroopsNumberSqrtThreshold)
            {
                hourlygen = (king.SquaresNumber * GlobalParameters.HourlyTroopsProductionBySquare) +
                    GlobalParameters.HourlyTroopProductionByAcademy;
            }
            else
            {
                hourlygen = GlobalParameters.TroopsNumberSqrtThreshold +
                    Math.Sqrt((king.SquaresNumber - GlobalParameters.TroopsNumberSqrtThreshold) * GlobalParameters.HourlyTroopsProductionBySquare) +
                    GlobalParameters.HourlyTroopProductionByAcademy;
            }

            int totalgen = (int)Math.Truncate(ts.TotalHours * hourlygen);
            king.AcademyTroops += totalgen;
            if (hourlygen != 0)
            {
                king.LastAcademyTroopsUpdate = king.LastAcademyTroopsUpdate.AddHours(totalgen / hourlygen);
            }

            king.AcademyTroops = Math.Min(king.AcademyTroops, (int)hourlygen * 72);
        }

        /// <summary>
        /// Get real number of academy troops.
        /// MUST be used in GUI instead of king.AcademyTroops on high level functions.
        /// </summary>
        /// <param name="king">The considered king</param>
        /// <returns>The real number of academy troops.</returns>
        public static int GetAcademyTroops(this King king)
        {
            king.UpdateAcademyTroops();
            return king.AcademyTroops;
        }

        /// <summary>
        /// Gets the maximum number of ppl someone can have in its academy.
        /// </summary>
        /// <param name="king">The considered king</param>
        /// <returns>See summary, please.</returns>
        public static int MaxAcademyTroops(this King king)
        {
            double hourlygen;
            if (king.SquaresNumber <= GlobalParameters.TroopsNumberSqrtThreshold)
            {
                hourlygen = (king.SquaresNumber * GlobalParameters.HourlyTroopsProductionBySquare) +
                    GlobalParameters.HourlyTroopProductionByAcademy;
            }
            else
            {
                hourlygen = GlobalParameters.TroopsNumberSqrtThreshold +
                    Math.Sqrt((king.SquaresNumber - GlobalParameters.TroopsNumberSqrtThreshold) * GlobalParameters.HourlyTroopsProductionBySquare) +
                    GlobalParameters.HourlyTroopProductionByAcademy;
            }

            return (int)(72 * hourlygen);
        }
    }
}
